int creagrafo2(void)
{
  int i,j,k,grp;
  struct link  tmplink;
  struct point tmp_point,look;
  vector<int> registro;
  vector<int>::iterator isth;
  queue<int> Buscados,Encontrado;
  queue<struct equival> Delqueue;
  int nombre,root_proc,signal,offset;
  int *parent,*halla;
  int current,sendproc,nfindings;
  int current_size,name_to_search;
  int name_finding;
  struct equival t ;
  vector <equival>::iterator older;
  vector <struct point> old_vertices ;        // sobre la descomposicion de dominio
  size_t buffersize;
  int *posbuf;
	  
  vector <point>::iterator loc_ver;
  //ofstream Salida1,Salida2 ;
  char fileout[100];
  
  /*sprintf(fileout,"Recivo.%d.dat",proc);
  cout << proc<<" "<<fileout << endl;
  Salida1.open(fileout);
  sprintf(fileout,"Mando.%d.dat",proc);
  Salida2.open(fileout);*/

  
  /*buffersize=(((10000+MPI_BSEND_OVERHEAD)*sizeof(int)));
  posbuf=(int *)malloc(numprocs*buffersize);

  MPI_Buffer_attach(posbuf,(numprocs-1)*buffersize);*/
  signal=0;
  
  for(root_proc=0;root_proc < numprocs ; root_proc ++)
  {
	  current_size= arista.size();
	  MPI_Bcast(&current_size,1,MPI_INT,root_proc,MPI_COMM_WORLD);
	  if(current_size==0)continue;

	  if(proc==root_proc)
	  {
		  for(i=0;i< arista.size();i++)
		  {
			  isth=find(registro.begin(),registro.end(),arista[i].local);
			  if(isth==registro.end()){ registro.push_back(arista[i].local);
			                             Buscados.push(arista[i].local); }
			  isth=find(registro.begin(),registro.end(),arista[i].externa);
			  if(isth==registro.end()){ registro.push_back(arista[i].externa);
			                             Buscados.push(arista[i].externa); }
		  }

		  //cout << "Soy el proceso : " << proc << endl <<flush;
		  //cout << "Registro: ";
		  //for(i=0;i<registro.size();i++)
		  //cout << registro[i] << " ";

		  //cout << endl;
		  do//cincronous
		  {	   
		   	  nombre = Buscados.front(); try {Buscados.pop();} catch (std::exception& X) {cerr<< " kk1 " <<X.what()<< endl;FIN;}
			  //Salida1 << "busco el : " << nombre << endl;
		     	  //ask each process for nombre 
		       	  for(sendproc=0;sendproc < numprocs ; sendproc ++)
			  {
			       	  if(sendproc==root_proc){ if(sendproc==numprocs-1)break; continue;}
      				  MPI_Send(&nombre,1,MPI_INT,sendproc,66,MPI_COMM_WORLD);
      				  //MPI_Bsend(&nombre,1,MPI_INT,sendproc,66,MPI_COMM_WORLD);
      				  MPI_Recv(&nfindings,1,MPI_INT,sendproc,67,MPI_COMM_WORLD,&status);
      				  if(nfindings<=0){ if(sendproc==numprocs-1)break; continue;}
				  //Salida1 << "del proceso " << sendproc << " recivi: " << nfindings << endl;
				  try{parent= new int [nfindings];}catch (std::exception& X) 
				  {cerr<< " klkklkll " << X.what()<< endl;FIN;}
				  MPI_Recv(&parent,nfindings,MPI_INT,sendproc,68,MPI_COMM_WORLD,&status);
				  
      				  for(k=0;k<nfindings;k++)
      				  {
      					  isth=find(registro.begin(),registro.end(),parent[k]);
      					  if(isth==registro.end())
      					  {
						//  Salida1 << parent << " " ;
      						  registro.push_back(parent[k]);
      						  Buscados.push(parent[k]); 
      					  }
      					  if(parent[k]<0)continue ;
      					  t.local   = nombre   ;
      					  t.externa = parent[k]   ; 
      					  arista.push_back(t)  ;
      				  }
				  try{delete [] parent;}catch (std::exception& X) {cerr<< " ssss3 " << X.what()<< endl;FIN;}
				  //Salida1 << endl;
  			  }
		  	  signal=1;
		   	  if(Buscados.empty())signal= -1;
		    	  MPI_Bcast(&signal,1,MPI_INT,root_proc,MPI_COMM_WORLD);
		  }while(signal>0);//cincronous

		  /*
		  cout << "Soy proceso : " << proc << endl;
		  cout << "Al final Registro: ";
		  for(i=0;i<registro.size();i++)
		  cout << registro[i] << " ";
		  cout << endl;*/

	  }
	  else
	  {
		  do //cincronous
		  {
		     	  MPI_Recv(&name_to_search,1,MPI_INT,root_proc,66,MPI_COMM_WORLD,&status);
			  //cout << "Estoy buscando el: "<< name_to_search << endl << flush; 
			  if(name_to_search<0) moco("LAPUTAQUETEPARIO");
		          if(!Encontrado.empty()) moco("LARECONCH");
   			  nfindings=0;
			  //cout << "encuentro proc "<< proc << endl;
      			  for(j=0;j<arista.size();j++)
   			  {
       				  if( name_to_search == arista[j].local)
       				  { 
	 				  name_finding=arista[j].externa ; 
			  		  nfindings++;
					  //cout << name_finding << "borrando 1 " << flush << endl;
					  Encontrado.push(name_finding);
				   	  Delqueue.push(arista[j]); 
					  continue;
					  //Salida2 << arista[j].local << " | "<< arista[j].externa << ") ";
				  }
       				  if( name_to_search == arista[j].externa )
       				  { 
	 				  name_finding=arista[j].local ; 
		 			  nfindings++; 
					  //cout << name_finding << "borrando 2 " << flush << endl;
					  Encontrado.push(name_finding);
			  		  Delqueue.push(arista[j]);
					  continue;
					  //Salida2 << arista[j].local << " | "<< arista[j].externa << ") ";
       				  }
   			  }
			  //cout << proc<<": tantos: " << Encontrado.size() << endl;
   			  if(!Delqueue.empty())
			  {
   				  do
   				  {
   				   if(Delqueue.empty())break;
   					  t = Delqueue.front(); try {Delqueue.pop();}catch (std::exception& X) {cerr<< " kk2 " << X.what()<< endl;FIN;}
   					  older = find_if( arista.begin(), arista.end(), comp_arista(t) );
   					  if(older == arista.end())
					  {
						  //cout << t.local << " ----  " << t.externa << endl <<flush;
						//  moco("HEY!!!!!!!!!!!\n");FIN;
					  }
					  try{arista.erase(older,older+1);} catch (std::exception& X) {cerr<< " kk3 " << X.what()<< endl;FIN;}
   				  }
   				  while(!Delqueue.empty());
			  }
			  //Salida2 << endl << "Envio: " << endl; 
   			  if(Encontrado.empty())
   			  {
				  //Salida2 << "NADA   ----" << endl;
       				  nfindings=-1;
       				  //MPI_Bsend(&nfindings,1,MPI_INT,root_proc,67,MPI_COMM_WORLD);
       				  MPI_Send(&nfindings,1,MPI_INT,root_proc,67,MPI_COMM_WORLD);
   			  }
   			  else
   			  {
       				  // va enviando y vaciando
       				  //MPI_Bsend(&nfindings,1,MPI_INT,root_proc,67,MPI_COMM_WORLD);
       				  MPI_Send(&nfindings,1,MPI_INT,root_proc,67,MPI_COMM_WORLD);
			          //cout << nfindings << " los hallados son " << Encontrado.size() << endl;
				  				  
				  j=0;
				  try{ halla= new int [nfindings];}catch (std::exception& X) {cerr<< " kk6 " << X.what()<< endl;FIN;}
       				  do
       				  {
	 				  try{halla[j] = Encontrado.front(); }
					  catch (std::exception& X) {cerr<< " ll3 " << X.what()<< endl;FIN;}
					  try{ Encontrado.pop();}
					  catch (std::exception& X) {cerr<< " kk3 " << X.what()<< endl;FIN;}
					  //cout << halla[j] << " - " << j <<endl;
					  j++;
				  }while(!Encontrado.empty());
		 			  
				  //MPI_Bsend(&halla,nfindings,MPI_INT,root_proc,68,MPI_COMM_WORLD);
				  MPI_Send(&halla,nfindings,MPI_INT,root_proc,68,MPI_COMM_WORLD);
				  try{delete [] halla;}catch (std::exception& X) {cerr<< " kk3 " << X.what()<< endl;FIN;}
   			  }
			  //cout << proc <<": quedaron: " << Encontrado.size() << endl <<flush;
			  
      			  MPI_Bcast(&signal,1,MPI_INT,root_proc,MPI_COMM_WORLD);
		  }while(signal>0);//cincronous
	  }

  }
  //free(posbuf);
  

  for(i=0;i< registro.size();i++)
  {
	  tmp_point.visitado = false          ;
	  tmp_point.distancia = 0             ;
	  tmp_point.padre = (vector <point>::iterator )NULL              ;
	  tmp_point.name = registro[i]        ;
	  grafo_vertices.push_back(tmp_point) ;
  }

  for(i=0;i< arista.size();i++)
  {
	  if(arista[i].local!=-1 && arista[i].externa!=-1)
	  {
			     
		  look.name=arista[i].local;
       		  //tmplink.r = find_if( grafo_vertices.begin(), grafo_vertices.end(), as_name(look) );
		  tmplink.r = grafo_vertices.begin() + arista[i].local   ;
		  look.name=arista[i].externa;
       		  //tmplink.l = find_if( grafo_vertices.begin(), grafo_vertices.end(), as_name(look) );
		  tmplink.l = grafo_vertices.begin() + arista[i].externa ; 
		  grafo_arista.push_back(tmplink)                ;
	  }
  }       

  //Salida1.close();
  //Salida2.close();

  try{registro.clear();}catch (std::exception& X) {cerr<< " kk3 " << X.what()<< endl;FIN;}
	
  //MPI_Buffer_detach(posbuf,&k);
  FIN;
 return 0; 
};

int groups_namesBFS(void)
{
	int i,j,k,ktot,sendproc,h,summ;
	int *rename, *subtot,*total;
	long int kk;
	struct point u,v,der,izq ; 
	vector <point>::iterator ptr ;
	cola Q;
	int root_proc;

	rename = new int [maxngrp*numprocs];
	subtot = new int [numprocs];
	for(i=0;i<maxngrp*numprocs;i++)
		rename[i] = -1; 

//	         cout << proc << " <-proc ; conectando grupos: "<< grafo_vertices.size() << endl;
	         for(i=0;i<grafo_vertices.size();i++)
	         {   
	             //cout << "G-Vertice "<< i <<endl; fflush(stdout);

                     if(grafo_vertices[i].visitado) continue ;
                     grafo_vertices[i].visitado  = true ;
                     grafo_vertices[i].distancia = 0    ;
                     //Encolar(Q, s);
	             Q.push(grafo_vertices[i]);
		
                     do
                     {
                        // extraemos el nodo u de la cola Q y exploramos 
	                // todos sus nodos adyacentes
                        u     = Q.front();
   	                Q.pop();
///	                 cout << "@ "<< Q.size() <<endl; fflush(stdout);
	       
                        for(j=0;j<grafo_arista.size();j++)
	                {
		             if( u.name == (*(grafo_arista[j].r)).name)
		             {
//	               cout << "U "<< u.name <<endl; fflush(stdout);
			           if(!(*(grafo_arista[j].l)).visitado)
			           {
                                        (*(grafo_arista[j].l)).visitado    = true            ;
                                        (*(grafo_arista[j].l)).distancia   = u.distancia + 1 ;
		                        (*(grafo_arista[j].l)).padre = grafo_vertices.begin()+(*(grafo_arista[j].r)).name;
		                        //(*(grafo_arista[j].l)).padre = 
					//	find_if( grafo_vertices.begin(), grafo_vertices.end(), 
					//			look_vertice_name(*(grafo_arista[j].r)) );
	                                Q.push(*(grafo_arista[j].l))     ;  //Encolar v en Q
			           }
		             }
		             if( u.name==(*(grafo_arista[j].l)).name)
		             {
			           if(!(*(grafo_arista[j].r)).visitado)
			           {
                                        (*(grafo_arista[j].r)).visitado    = true            ;
                                        (*(grafo_arista[j].r)).distancia   = u.distancia + 1 ;
		                        (*(grafo_arista[j].r)).padre       = grafo_vertices.begin()+(*(grafo_arista[j].l)).name;
		                        //(*(grafo_arista[j].r)).padre = 
				        //	find_if( grafo_vertices.begin(), grafo_vertices.end(), 
				        //			look_vertice_name(*(grafo_arista[j].l)) );
	                                Q.push(*(grafo_arista[j].r));//Encolar(Q, v);
			           }
		             }
	                }
                     }while(!Q.empty());
	             //agotadas todas las adyacencias salimos
	         }

		
		 //renombrando padres 
	         universalname=0;
	         for(i=0;i<grafo_vertices.size();i++)
	         {
		      u=grafo_vertices[i];
	              ptr=u.padre;
	              // es padre ?
		      if( ptr ==(vector <point>::iterator )NULL)
			      universalname++;
	         }
		 
		 for(i=0;i<numprocs;i++)
			 subtot[i]=0;
		 subtot[proc] = universalname;
		 MPI_Allreduce(&subtot,&total,numprocs,MPI_INT,MPI_SUM,MPI_COMM_WORLD);

		 summ=0;
		 for(i=0;i<=proc;i++)
		 {
			 subtot[i]=subtot[i]+summ;
			 summ = summ+ subtot[i];
		 }
		 
	         universalname=subtot[proc];
	         for(i=0;i<grafo_vertices.size();i++)
	         {
		      u=grafo_vertices[i];
	              ptr=u.padre;
	
	              // es padre ?
		      if( ptr ==(vector <point>::iterator )NULL)
		      {
			      rename[grafo_vertices[i].name] =universalname; 
			      universalname++;
		      }
	         }
		
		 
	         for(i=0;i<grafo_vertices.size();i++)
   	         {
	      	      u=grafo_vertices[i];
	              ptr=u.padre;

		      // es hijo de
		      if( ptr !=(vector <point>::iterator )NULL)
	      	      {
		      	      do
		 	      {
			           v=*ptr; ptr=v.padre;
                                   if(ptr==(vector <point>::iterator)NULL)
				           break;
  		              }while(1);
	   	              if(grafo_vertices[i].name<maxngrp*numprocs)
			      {
				      rename[grafo_vertices[i].name] = rename[v.name] ;
			      }
			      else
			      {
				      LGREEN;
				      cout<< "la cagaste aca  " << proc << " " <<grafo_vertices[i].name <<endl;
				      DEFA;
			      }
	   	      }
 	         }
		 
	for(i=0;i<maxngrp*numprocs;i++)
	{
            k = rename[i]>-1 ? 1 : 0; ktot=0;
            MPI_Allreduce(&k,&ktot,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);
	    if(ktot>1)
	    {
		    cout << rename[i] << " | " << proc << " -- " << ktot << endl;
		    moco("mas de uno en rename\n");FIN;
	    }
	    if(ktot==0)
	    {
		    //el grupo no existe pero eso esta permitido
		    if(i==maxngrp*numprocs-1)break;
		    continue;
	    }
	    k = k==1 ? proc : -1;
	    MPI_Allreduce(&k,&ktot,1,MPI_INT,MPI_MAX,MPI_COMM_WORLD);
	    MPI_Barrier(MPI_COMM_WORLD);
            MPI_Bcast(&rename[i],1,MPI_INT,ktot,MPI_COMM_WORLD);
	    MPI_Barrier(MPI_COMM_WORLD);
	}

 
        /*	
	ofstream Salida ;
      	char fileout[100];
      	sprintf(fileout,"Nombres.%d.dat",proc);

      	Salida.open(fileout);
	for(i=0;i<maxngrp*numprocs;i++)
	{
		if(rename[i]>-1)
			Salida << i << " renombrado a: " << rename[i] << endl;
	}
      	Salida.close();*/

	for(i=0;i<particle.size();i++)
	{
		particle[i].Idgrupo=rename[particle[i].Idgrupo];
                if(particle[i].Idgrupo>=0)numero[particle[i].Idgrupo]++;
	}
	return 0;
};

